{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 此文件的作用：\n",
    "#\n",
    "#\n",
    "#\n",
    "# 要求： "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from lxml import etree\n",
    "from tqdm import tqdm\n",
    "import requests\n",
    "import time\n",
    "import shutil \n",
    "import os\n",
    "import urllib.request\n",
    "\n",
    "from PyQt5 import  QtWidgets\n",
    "from PyQt5.QtWidgets import *\n",
    "from PyQt5.QtGui import *\n",
    "from PyQt5.QtCore import *\n",
    "import sys\n",
    "import threading\n",
    "from threading import Event\n",
    "import copy\n",
    "import datetime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "ZUO_PIN_INFO_CONFIG = \"zuo_pin_shu_from_dou_yin_.txt\"\n",
    "XIN_ZENG_INFO_CONFIG = \"xin_zeng_zuo_pin_shu.txt\"\n",
    "LOG_FILE_PATH = \"log.txt\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class Logger(object):\n",
    "    def __init__(self, filename=\"Default.log\"):\n",
    "        self.terminal = sys.stdout\n",
    "        self.filename = filename\n",
    "        \n",
    "    def write(self, message):\n",
    "        self.log = open(self.filename, \"a\", encoding=\"utf-8\")  # 防止编码错误\n",
    "        self.terminal.write(message)\n",
    "        self.log.write(message)\n",
    "        self.log.close()\n",
    "    def flush(self):\n",
    "        pass\n",
    "    def reset(self):\n",
    "        #self.log.close()\n",
    "        sys.stdout=self.terminal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "98888\n",
      "从文件zuo_pin_shu_from_dou_yin_.txt中，共读取到18个主页的作品量数据\n",
      "从文件xin_zeng_zuo_pin_shu.txt中，共读取到7条新增记录\n"
     ]
    }
   ],
   "source": [
    "sys.stdout = Logger(LOG_FILE_PATH) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 从文件中加载原有作品数\n",
    "def load_zuo_pin_shu_from_file(zuo_pin_shu_save_path):\n",
    "    zuo_pin_shu_of_homepage_list = []\n",
    "    if not os.path.exists(zuo_pin_shu_save_path):\n",
    "        return zuo_pin_shu_of_homepage_list\n",
    "    file_read = open(zuo_pin_shu_save_path, \"r\", encoding='UTF-8')\n",
    "    lines = file_read.readlines()\n",
    "    for line in lines:\n",
    "        line = line.strip()\n",
    "        if len(line) < 4:\n",
    "            continue\n",
    "        data_list = line.split(\"\\t\")\n",
    "        assert len(data_list) == 3, \"{}内数据格式不合法\".format(zuo_pin_shu_save_path)\n",
    "        zuo_pin_shu_of_homepage_list.append((data_list[0], data_list[1], int(data_list[2])))\n",
    "    file_read.close()\n",
    "    print(\"从文件{}中，共读取到{}个主页的作品量数据\".format(zuo_pin_shu_save_path, len(zuo_pin_shu_of_homepage_list)))\n",
    "    return zuo_pin_shu_of_homepage_list\n",
    "\n",
    "# 将作品数保存到文件中\n",
    "def save_zuo_pin_shu_to_file(html_info_list, zuo_pin_shu_save_path):\n",
    "    file_write = open(zuo_pin_shu_save_path, \"w\", encoding='UTF-8')\n",
    "    for html_info in html_info_list:\n",
    "        file_write.write(\"{}\\t{}\\t{}\\n\".format(html_info[0], html_info[1], html_info[2]))\n",
    "    file_write.close()\n",
    "    print(\"将作品数保存到文件{}中\".format(zuo_pin_shu_save_path))\n",
    "    return True\n",
    "\n",
    "# 从文件中加载新增数记录\n",
    "def load_xin_zeng_shu_from_file(xin_zeng_save_path):\n",
    "    xin_zeng_info_list = []\n",
    "    if not os.path.exists(xin_zeng_save_path):\n",
    "        return xin_zeng_info_list\n",
    "    file_read = open(xin_zeng_save_path, \"r\", encoding='UTF-8')\n",
    "    lines = file_read.readlines()\n",
    "    for line in lines:\n",
    "        line = line.strip()\n",
    "        if len(line) < 4:\n",
    "            continue\n",
    "        data_list = line.split(\"\\t\")\n",
    "        assert len(data_list) == 3, \"{}内数据格式不合法\".format(xin_zeng_save_path)\n",
    "        datetime_ = datetime.datetime.strptime(data_list[2],\"%Y-%m-%d %H:%M:%S\")\n",
    "        #localtime_ = time.localtime(time.mktime(datetime_.timetuple()))\n",
    "        xin_zeng_info_list.append((data_list[0], int(data_list[1]), datetime_))\n",
    "    file_read.close()\n",
    "    print(\"从文件{}中，共读取到{}条新增记录\".format(xin_zeng_save_path, len(xin_zeng_info_list)))\n",
    "    return xin_zeng_info_list\n",
    "\n",
    "# 将新增作品数保存到文件中\n",
    "def save_xin_zeng_shu_to_file(xin_zeng_info_list, xin_zeng_save_path):\n",
    "    file_write = open(xin_zeng_save_path, \"w\", encoding='UTF-8')\n",
    "    for xin_zeng_info in xin_zeng_info_list:\n",
    "        #time_str = time.strftime('%Y-%m-%d %H:%M:%S', xin_zeng_info[2])  \n",
    "        time_str = str(xin_zeng_info[2].strftime(\"%Y-%m-%d %H:%M:%S\") )\n",
    "        file_write.write(\"{}\\t{}\\t{}\\n\".format(xin_zeng_info[0], xin_zeng_info[1], time_str))\n",
    "    file_write.close()\n",
    "    print(\"将新增数保存到文件{}中\".format(xin_zeng_save_path))\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "从文件zuo_pin_shu_from_dou_yin_.txt中，共读取到18个主页的作品量数据\n",
      "从文件xin_zeng_zuo_pin_shu.txt中，共读取到7条新增记录\n"
     ]
    }
   ],
   "source": [
    "g_html_info_list = load_zuo_pin_shu_from_file(ZUO_PIN_INFO_CONFIG)\n",
    "g_xin_zeng_info_list = load_xin_zeng_shu_from_file(XIN_ZENG_INFO_CONFIG)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('https://www.douyin.com/user/MS4wLjABAAAAqG3RbRCnBRRz57G_D9pwzdYRJupTJ3DFZzF-QIUWRTcntGW9KxyyL0ApNvqdpbo-',\n",
       "  1,\n",
       "  datetime.datetime(2023, 1, 3, 14, 0, 54)),\n",
       " ('https://www.douyin.com/user/MS4wLjABAAAAmxDdJlhLZ5N2FiKMItYzK3JYDZuEbuxuPPqR_IoDwjiu4Vyd2kj4xkkn522wOqmn',\n",
       "  1,\n",
       "  datetime.datetime(2023, 1, 3, 14, 1, 8)),\n",
       " ('https://www.douyin.com/user/MS4wLjABAAAAcL_omw4BmOJrVnpjIsQyWwNZqHmKuUCqZQwyAq-hDoU',\n",
       "  1,\n",
       "  datetime.datetime(2023, 1, 3, 14, 53, 55)),\n",
       " ('https://www.douyin.com/user/MS4wLjABAAAAWRn3A5LRkpMOgXFh_rX6lAkWRoNOQKzhkVF-np4dW-1JNdPXpu58HnCZFiM1r4aF',\n",
       "  1,\n",
       "  datetime.datetime(2023, 1, 3, 14, 56, 57)),\n",
       " ('https://www.douyin.com/user/MS4wLjABAAAAcL_omw4BmOJrVnpjIsQyWwNZqHmKuUCqZQwyAq-hDoU',\n",
       "  1,\n",
       "  datetime.datetime(2023, 1, 3, 15, 25, 2)),\n",
       " ('https://www.douyin.com/user/MS4wLjABAAAA9wVtWLbBg1MVYewymhM3jm3wOz0pcyudPD3j9dazv3uBnvlDuCJGtWFMAM4EwdqW',\n",
       "  1,\n",
       "  datetime.datetime(2023, 1, 3, 16, 7, 16)),\n",
       " ('https://www.douyin.com/user/MS4wLjABAAAAqG3RbRCnBRRz57G_D9pwzdYRJupTJ3DFZzF-QIUWRTcntGW9KxyyL0ApNvqdpbo-',\n",
       "  1,\n",
       "  datetime.datetime(2023, 1, 3, 16, 43, 11))]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g_xin_zeng_info_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def get_work_info(html_path):\n",
    "    try:\n",
    "        response = requests.get(html_path)\n",
    "        #time.sleep(0.5)\n",
    "        html_serial = etree.HTML(response.text)\n",
    "        page_names = html_serial.xpath(\"//span/span\")\n",
    "        page_name = page_names[0].xpath(\"string(.)\")\n",
    "        #print(\"主页名:{}\".format(page_name))\n",
    "        user_tab_count = html_serial.xpath(\"//span[@data-e2e='user-tab-count']\")\n",
    "        if len(user_tab_count) not in [1, 2]:\n",
    "            print(\"不合法的html:{}\".format(user_tab_count))\n",
    "            return -1, \"\"\n",
    "        #print(user_tab_count[0])\n",
    "        count_str = user_tab_count[0].xpath(\"string(.)\")\n",
    "        count_int = int(count_str)\n",
    "        return count_int, page_name\n",
    "    except Exception as e:\n",
    "        print(\"！！！！获得的页面的数据不对，可能有反爬虫\")\n",
    "        print(e)\n",
    "        return -1, \"\"\n",
    "    return -1, \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1108, '咿呀简笔画')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_work_info(\"https://www.douyin.com/user/MS4wLjABAAAA0Z3rjDlui3X8osmm63EC4emHXoZi8TbTh_nIgU8RMGw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def do_one_loop(html_info_list, input_event, table):\n",
    "    for i, html_info in enumerate(html_info_list):\n",
    "        html_path, _, _ = html_info\n",
    "        count_int, page_name = get_work_info(html_path)\n",
    "        if -1 == count_int:\n",
    "            print(\"【{}】【{}】！！！！爬虫失败\".format(i, html_path))\n",
    "        else:\n",
    "            print(\"【{}】【{}】作品数是:{}\".format(i, html_path, count_int))\n",
    "            if count_int > html_info_list[i][2] and html_info_list[i][2] == 0:   \n",
    "                html_info_list[i] = (html_path, page_name, count_int)\n",
    "                save_zuo_pin_shu_to_file(html_info_list, ZUO_PIN_INFO_CONFIG)\n",
    "            if count_int > html_info_list[i][2] and html_info_list[i][2] != 0:\n",
    "                print(\"^_^发现了新作品\")\n",
    "                xin_zeng_count = count_int - html_info_list[i][2]\n",
    "                datetime_ = datetime.datetime.now()\n",
    "                # time.localtime(time.time())\n",
    "                g_xin_zeng_info_list.append((html_path, xin_zeng_count, datetime_))\n",
    "                save_xin_zeng_shu_to_file(g_xin_zeng_info_list, XIN_ZENG_INFO_CONFIG)\n",
    "                \n",
    "                html_info_list[i] = (html_path, page_name, count_int)\n",
    "                save_zuo_pin_shu_to_file(html_info_list, ZUO_PIN_INFO_CONFIG)\n",
    "           \n",
    "                \n",
    "            #table.tableView.setEnabled(True)\n",
    "            table.model.setItem(i, 1, QStandardItem(page_name)) \n",
    "            #table.tableView.setEnabled(False)\n",
    "        \n",
    "        if True == input_event.wait(1.5):\n",
    "            print(\"do_one_loop, 被要求退出\")\n",
    "            break\n",
    "        #time.sleep(1.5)\n",
    "        \n",
    "#i_loop_count = 0 \n",
    "#while True:        \n",
    "#    i_loop_count += 1\n",
    "#    print(\"【{}】\".format(i_loop_count))\n",
    "#    do_one_loop(g_html_info_list)\n",
    "#    time.sleep(20)\n",
    "###"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 更新新增作品数 \n",
    "def update_xin_zeng_shu(table):\n",
    "    global g_html_info_list\n",
    "    \n",
    "    #localtime_now = time.localtime(time.time())\n",
    "    datetime_now = datetime.datetime.now()\n",
    "    for i, html_info in enumerate(g_html_info_list):\n",
    "        html_path, _, _ = html_info\n",
    "        i_count = 0\n",
    "        for xin_zeng_info in g_xin_zeng_info_list:\n",
    "            html_url, xin_zeng_count, datetime_ = xin_zeng_info\n",
    "            if html_url != html_path:\n",
    "                continue\n",
    "            intal_seconds = (datetime_now -datetime_).seconds\n",
    "            if intal_seconds > 30*60:\n",
    "                continue\n",
    "            i_count += xin_zeng_count\n",
    "        \n",
    "        item = QStandardItem(str(i_count))\n",
    "        if i_count > 0:\n",
    "            item.setBackground(QBrush(QColor(255, 0, 0, 250)))\n",
    "        else:\n",
    "            item.setBackground(QBrush(QColor(255, 255, 255, 255)))\n",
    "        item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)\n",
    "        table.model.setItem(i, 2, item) \n",
    "\n",
    "          "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "g_Event = Event()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def monitor_thread(table):\n",
    "    print(\"===>线程名称:{} 参数：{} 开始时间:{}\".format(threading.current_thread().name, table, time.strftime(\"%Y-%m-%d %H:%M%S\")))\n",
    "    print(\"监控的主页共{}个:{}\".format(len(g_html_info_list), g_html_info_list))\n",
    "    \n",
    "    i_loop_count = 0  \n",
    "    while True:        \n",
    "        i_loop_count += 1\n",
    "        print(\"【{}】\".format(i_loop_count))\n",
    "        do_one_loop(g_html_info_list, g_Event, table)\n",
    "        # 更新新增作品数 \n",
    "        update_xin_zeng_shu(table)\n",
    "   \n",
    "        if True == g_Event.wait(20):\n",
    "            print(\"monitor_thread, 被要求退出\")\n",
    "            break\n",
    "        #time.sleep(20)\n",
    "    \n",
    "    print(\"<===线程名称:{} 开始时间:{}\".format(threading.current_thread().name, time.strftime(\"%Y-%m-%d %H:%M%S\")))\n",
    "    \n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class ReadOnlyDelegate(QtWidgets.QStyledItemDelegate):\n",
    "    def createEditor(self, parent, option, index):\n",
    "        return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "class Table(QWidget):\n",
    " \n",
    "\tdef __init__(self, arg=None):\n",
    "\t\tsuper(Table, self).__init__(arg)\n",
    "\t\tself.setWindowTitle(\"抖音新作品监控\")\n",
    "        \n",
    "\t\toperatorLayout = QHBoxLayout()\n",
    "\t\tself.startBtn = QPushButton(\"开始监控\")\n",
    "\t\tself.stopBtn = QPushButton(\"停止监控\")\n",
    "\t\tself.addBtn = QPushButton(\"添加主页\")\n",
    "\t\tself.delBtn = QPushButton(\"删除主页\")\n",
    "\t\toperatorLayout.addWidget(self.startBtn)\n",
    "\t\toperatorLayout.addWidget(self.stopBtn)\n",
    "\t\toperatorLayout.addWidget(self.addBtn)\n",
    "\t\toperatorLayout.addWidget(self.delBtn)\n",
    "\n",
    "        # 按钮的信号槽连接\n",
    "\t\tself.startBtn.clicked.connect(self.startBtnFun)\n",
    "\t\tself.stopBtn.clicked.connect(self.stopBtnFun)\n",
    "\t\tself.addBtn.clicked.connect(self.addBtnFun)\n",
    "\t\tself.delBtn.clicked.connect(self.delBtnFun)\n",
    "        \n",
    "\t\tself.resize(500,300);\n",
    "\t\tself.model=QStandardItemModel(0, 3);\n",
    "\t\tself.model.setHorizontalHeaderLabels(['主页URL', '主页名', '近半小时作品数'])\n",
    "\t\t#for i, html_path in enumerate(html_path_list):\n",
    "\t\t#\tself.model.setItem(i, 0, QStandardItem(\"%s\"%(html_path))) \n",
    "\n",
    "\t\t\n",
    "\t\tself.tableView=QTableView()\n",
    "\t\tself.tableView.setModel(self.model)\n",
    "\t\tself.tableView.setItemDelegateForColumn(1, ReadOnlyDelegate())\n",
    "\t\t#self.tableView.setItemDelegateForColumn(2, ReadOnlyDelegate())\n",
    "\t\t#下面代码让表格100填满窗口\n",
    "\t\tself.tableView.horizontalHeader().setStretchLastSection(True)\n",
    "\t\tself.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)\n",
    "        \n",
    "\t\tself.timeLabel = QLabel(\"此次运行时间:\")\n",
    "\t\tself.meLabel = QLabel(\"作者:chenyujing VX:15280006510\")\n",
    "\t\tlabelLayout = QHBoxLayout()\n",
    "\t\tlabelLayout.addWidget(self.timeLabel)\n",
    "\t\tlabelLayout.addWidget(self.meLabel)\n",
    "        \n",
    "\t\tdlgLayout=QVBoxLayout()\n",
    "\t\tdlgLayout.addLayout(operatorLayout);\n",
    "\t\tdlgLayout.addWidget(self.tableView)\n",
    "\t\tdlgLayout.addLayout(labelLayout)\n",
    "        \n",
    "\t\tself.setLayout(dlgLayout)\n",
    "        \n",
    "\t\t# 创建运行时间的定时器\n",
    "\t\tself.Timer = QTimer()\n",
    "    \n",
    "\tdef reload(self, html_info_list = []):\n",
    "\t\tfor i, html_info in enumerate(html_info_list):\n",
    "\t\t\thtml_path, page_name, work_count = html_info\n",
    "\t\t\tself.model.setItem(i, 0, QStandardItem(\"%s\"%(html_path))) \n",
    "\t\t\tself.model.setItem(i, 1, QStandardItem(\"%s\"%(page_name))) \n",
    "\t\tupdate_xin_zeng_shu(self) \n",
    "        \n",
    "\tdef addBtnFun(self):\n",
    "\t\tprint('--- addBtnFun ---')\n",
    "\t\tvalue, ok = QInputDialog.getText(self, \"添加主页\", \"请输入主页url:\", QLineEdit.Normal, \"\")\n",
    "\t\tif ok and value:\n",
    "\t\t\tself.model.setItem(len(g_html_info_list), 0, QStandardItem(\"%s\"%(value))) \n",
    "\t\t\tg_html_info_list.append((value, \"\", 0))\n",
    "\t\treturn\n",
    "    \n",
    "\tdef delBtnFun(self):\n",
    "\t\tprint('--- delBtnFun ---')\n",
    "\t\trow = self.tableView.currentIndex().row()        #获取被选择的行数\n",
    "\t\tif -1 == row:\n",
    "\t\t\tQMessageBox.information(self, \"提示\", \"请在表头选择整行后进行删除\", QMessageBox.Yes)\n",
    "\t\t\treturn\n",
    "\t\tprint(\"移除第{}行\".format(row))\n",
    "\t\t#indices = self.tableView.selectionModel().selectedRows() \n",
    "\t\t#for index in sorted(indices):\n",
    "\t\t#\tprint(\"移除第{}行\".format(index.row()))\n",
    "\t\tself.model.removeRow(row) \n",
    " \n",
    "\tdef startBtnFun(self):\n",
    "\t\tglobal g_html_info_list\n",
    "\t\tprint('--- startBtnFun ---')\n",
    "\t\tcount_row = self.model.rowCount()\n",
    "\t\tprint(\"共有{}行\".format(count_row))\n",
    "\t\thtml_info_list = copy.deepcopy(g_html_info_list)\n",
    "\t\tg_html_info_list = []\n",
    "\t\tfor i in range(count_row):\n",
    "\t\t\turl = self.model.data(self.model.index(i,0))\n",
    "\t\t\tprint(\"获取的URL:{}\".format(url))\n",
    "\t\t\tbFound = False\n",
    "\t\t\tfor j, html_info in enumerate(html_info_list):\n",
    "\t\t\t\thtml_path, page_name, work_count = html_info\n",
    "\t\t\t\tif url == html_path:\n",
    "\t\t\t\t\tbFound = True\n",
    "\t\t\t\t\tg_html_info_list.append((url, page_name, work_count))\n",
    "\t\t\tif bFound == False:\n",
    "\t\t\t\tg_html_info_list.append((url, \"\", 0))\n",
    "\t\tsave_zuo_pin_shu_to_file(g_html_info_list, ZUO_PIN_INFO_CONFIG)\n",
    "        \n",
    "\t\tg_Event.clear()\n",
    "\t\t#创建线程\n",
    "\t\tthread = threading.Thread(target = monitor_thread, args = (self, ))  \n",
    "\t\tthread.start()\n",
    "        \n",
    "\t\tself.startBtn.setEnabled(False)\n",
    "\t\tself.addBtn.setEnabled(False)\n",
    "\t\tself.delBtn.setEnabled(False)\n",
    "\t\t#self.tableView.setEnabled(False)\n",
    "        \n",
    "\t\t# 定时器每500ms工作一次\n",
    "\t\tself.Timer.start(500)\n",
    "\t\t# 建立定时器连接通道  注意这里调用TimeUpdate方法，不是方法返回的的结果，所以不能带括号，写成self.TimeUpdate()是不对的\n",
    "\t\tself.Timer.timeout.connect(self.TimeUpdate)\n",
    "\t\tself.datetimeStart = datetime.datetime.now()\n",
    "\n",
    "\t\treturn\n",
    "    \n",
    "\tdef stopBtnFun(self):\n",
    "\t\tprint('--- stopBtnFun ---')\n",
    "\t\tg_Event.set()\n",
    "        \n",
    "\t\tself.startBtn.setEnabled(True)\n",
    "\t\tself.addBtn.setEnabled(True)\n",
    "\t\tself.delBtn.setEnabled(True)\n",
    "\t\t#self.tableView.setEnabled(True)\n",
    "        \n",
    "\t\tself.Timer.stop()\n",
    "\t\treturn\n",
    "    \n",
    "\tdef TimeUpdate(self):\n",
    "\t\tdatetimeNow = datetime.datetime.now()\n",
    "\t\tintal_seconds = (datetimeNow - self.datetimeStart).seconds\n",
    "\t\tintal_hours = int(int(intal_seconds)/3600)\n",
    "\t\tintal_seconds = intal_seconds - 3600*intal_hours\n",
    "\t\tintal_minutes = int(int(intal_seconds)/60)\n",
    "\t\tintal_seconds = intal_seconds - 60*intal_minutes\n",
    "\t\tstrDiplay = \"监控正在进行:\" + str(intal_hours) + \"时\" + str(intal_minutes) + \"分\" + str(intal_seconds) + \"秒\"\n",
    "\t\tself.timeLabel.setText(strDiplay)\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "ename": "SystemExit",
     "evalue": "0",
     "output_type": "error",
     "traceback": [
      "An exception has occurred, use %tb to see the full traceback.\n",
      "\u001b[1;31mSystemExit\u001b[0m\u001b[1;31m:\u001b[0m 0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\chenyujing\\AppData\\Local\\conda\\conda\\envs\\py35\\lib\\site-packages\\IPython\\core\\interactiveshell.py:2870: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n",
      "  warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n"
     ]
    }
   ],
   "source": [
    "if __name__ == '__main__':\n",
    "\tapp = QApplication(sys.argv)\t\n",
    "\ttable = Table()\n",
    "\ttable.reload(g_html_info_list)\n",
    "\ttable.show()\n",
    "\tsys.exit(app.exec_())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
